package com.semlab.client.fwk.ap.mvp;

import java.util.logging.Logger;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Image;
import com.semlab.client.bundle.Resources;
import com.semlab.client.fwk.GoToPlaceRequestEvent;
import com.semlab.client.fwk.ap.Place;
import com.semlab.client.fwk.ap.mvp.BaseMVP.Presenter;
import com.semlab.client.fwk.ap.mvp.BaseMVP.View;
import com.semlab.client.req.RequestFactory;

public abstract class BasePresenter<D extends View<?>> extends AbstractActivity implements Presenter<D> {
	
	protected Logger log = Logger.getLogger(getClass().getName());

	protected EventBus eventBus;

	protected Place place;
	protected D display;
	private AcceptsOneWidget container;
	
	protected RequestFactory requestFactory;

	private boolean showLoading = true;

	public BasePresenter(Place place, D display, RequestFactory requestFactory) {
		this.display = display;
		this.place = place;
		this.requestFactory = requestFactory;
	}
	
	public BasePresenter(Place place, D display, RequestFactory requestFactory, boolean showLoading) {
		this(place, display, requestFactory);
		this.showLoading  = showLoading;
	}

	@Override
	public final void start(AcceptsOneWidget container, EventBus eventBus) {
		this.container = container;
		this.eventBus = eventBus;
		display.onPresenterStart();
//		container.setWidget(display);
		log.fine(":: starting presenter: " + getClass().getName());
		if(showLoading)
		showLoading();
		onStart();
	}

	public void goTo(com.google.gwt.place.shared.Place newPlace) {
		fireEvent(new GoToPlaceRequestEvent(newPlace));
	}
	
	public void fireEvent(GwtEvent<?> event) {
		if(eventBus != null) {
			log.fine(":: firing event ");
			eventBus.fireEvent(event);
		} else {
			log.warning("activity is not active so can't fire events");
		}
	}
	
	public <H extends EventHandler> HandlerRegistration handleEvent(Type<H> type, H handler) {
		if(eventBus != null) {
			log.fine("adding event handler");
			return eventBus.addHandler(type, handler);
		} else {
			log.warning("activity is no active so can't handle events");
			return null;
		}
	}
	
	@Override
	public String mayStop() {
		display.onPresenterStop();
		return super.mayStop();
	}
	
	protected final void setViewInContainer(){
		container.setWidget(display);
	}
	
	private void showLoading(){
		container.setWidget(new Image(Resources.INSTANCE.loading()));
	}
	
	protected abstract void onStart();	
}
